// TestDlg.cpp : implementation file
//

#include "stdafx.h"
#include "RFUsbDemo.h"
#include "TestDlg.h"

#include "umfh.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#pragma comment(lib,"S8ce.lib")

extern int CurCardtype;
/////////////////////////////////////////////////////////////////////////////
// CTestDlg dialog


CTestDlg::CTestDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CTestDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CTestDlg)
	m_strMsg = _T("");
	//}}AFX_DATA_INIT
}


void CTestDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CTestDlg)
	DDX_Text(pDX, IDC_EDT_MSG, m_strMsg);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CTestDlg, CDialog)
	//{{AFX_MSG_MAP(CTestDlg)
	ON_BN_CLICKED(IDC_BTN_TEST, OnBtnTest)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTestDlg message handlers

void CTestDlg::OnBtnTest() 
{
	// TODO: Add your control notification handler code here
	ClearMsg();
	int st=0;

	switch(CurCardtype)
	{
	case 1: //M1
		{
			
			int secNr=2;
			int blk=8;
			CString strErr;


			//==========================
			//装载要操作的页的密码
			unsigned char keybuf[7]={0xff,0xff,0xff,0xff,0xff,0xff};
			st=fw_load_key(icdev,0,secNr,keybuf);
			if(st!=0)
			{
				showMsg("loadkey Error!");
				CString str;//for test
				str.Format(_T("%d"),st);
				showMsg(str);
				return;
			}
			showMsg("loadkey OK!");
			
			
			//=================================
			//寻卡，获得卡号
			
			unsigned int cardtype;
			st=fw_request(icdev,1,&cardtype);//1模式寻卡
			if(st!=0)
			{
				showMsg("request Error!");
				return;
			}
			else
			{	
				showMsg("request Ok!");
			}
			
			
			unsigned long cardsnr;
			CString linstr;
			st=fw_anticoll(icdev,0,&cardsnr);
			if(st!=0)
			{
				showMsg("anticoll Error!");
				return;
			}
			showMsg("anticoll OK!");
			
			linstr.Format(_T("Card Number: %u"),cardsnr);
			showMsg(linstr);
			
			unsigned char cardSize;
			st=fw_select(icdev,cardsnr,&cardSize);
			if(st!=0)
			{
				showMsg("select Error!");
				strErr.Format(L"Error code: %d",st);
				showMsg(strErr);
				return;
			}
			showMsg("select OK!");
			
			//==========================
			//验证要操作的扇区
			st=fw_authentication(icdev,0,secNr);
			if(st!=0)
			{
				showMsg("authencation Error!");
				return;
			}
			showMsg("authencation OK!");
			//==========================
			//读卡数据测试
			unsigned char blkData[60];
			unsigned char showData[256]={0};
			st=fw_read(icdev,blk,blkData);
			if(st!=0)
			{
				showMsg("read Error!");
				return;
			}
			showMsg("read OK!");
			hex_a(showData,blkData,32);//convertUcharToHexstr(showData,blkData,32);
			showMsg((char *)showData);
			
			//==============================
			//写卡数据测试
			unsigned char wtData[20]={0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66};
			st=fw_write(icdev,blk,wtData);
			if(st!=0)
			{
				showMsg("write Error!");
				return;
			}
			showMsg("write OK!");
			//================================
			//把数据块当作是值块来操作
			//初始化值
			st=fw_initval(icdev,blk,1000);//初始化为1000
			if(st!=0)
			{
				showMsg("initval Error!");
				return;
			}
			showMsg("initval OK!");
			
			//==================================
			//增加值
			st=fw_increment(icdev,blk,80);
			if(st!=0)
			{
				showMsg("increment Error!");
				return;
			}
			st=fw_transfer(icdev,blk);
			if(st){
				strErr.Format(_T("transfer Error,Code: %d"),st);
				showMsg(strErr);
				return;
			}
			showMsg("increment OK!");


			//==================================
			//减值
			st=fw_decrement(icdev,blk,60);
			if(st!=0){
				showMsg("decrement Error!");
				return ;
			}
			st=fw_transfer(icdev,blk);
			if(st){
				strErr.Format(_T("transfer Error,Code: %d"),st);
				showMsg(strErr);
				return;
			}

			showMsg("decrement OK!");

			//==================================
			//读值
			unsigned long read_val;
			CString strval;
			st=fw_readval(icdev,blk,&read_val);
			if(st!=0){
				showMsg("read value error!");
				strErr.Format(_T("Error Code: %d"),st);
				showMsg(strErr);
				return;
			}
			strval.Format(L"value: %u",read_val);
			showMsg(strval);
			
			
			//==================================
			//修改密码
			unsigned char NewkeyA[7]={0x11,0x22,0x33,0x44,0x55,0x66};// 新密码A
			unsigned char CtrlBt[5]={0xff,0x07,0x80,0x69};//控制字节，建议不要改动这个值
			unsigned char keyB[7]={0xff,0xff,0xff,0xff,0xff,0xff};//密码B,建议不要改动这个值
			st=fw_changeb3(icdev,secNr,NewkeyA,CtrlBt,0,keyB)||fw_halt(icdev);//第三个参数设为0
			if(st!=0)
			{
				showMsg("changekey Error!");
				strErr.Format(L"error code: %d\r\n",strErr);
				showMsg(strErr);
				return;
			}
			showMsg("changekey OK!");
			
			//改回原来的默认密码
			unsigned long cardtag;
			
			st=fw_load_key(icdev,0,secNr,NewkeyA);//先装载新密码
			if(st!=0)
			{
				showMsg("New key load Error!");
				return;
			}
			showMsg("New key load OK!");
			
			st=fw_card(icdev,1,&cardtag);//先寻卡
			st=fw_authentication(icdev,0,secNr);//验证扇区
			
			st=fw_changeb3(icdev,secNr,keybuf,CtrlBt,0,keyB)||fw_halt(icdev);//第三个参数设为0
			if(st!=0)
			{
				showMsg("key has NOT been changed to old!");
				return;
			}
			showMsg("key has been changed to old!");
			
		}
		break;
		case 5://FCPU
			{

				CString strError;
				//射频复位
				st=fw_reset((HANDLE)icdev,3);
				if(st!=0){
					showMsg("RF reset error");
					return;
				}
				//寻卡
				CString strCard;
				unsigned long snCard;
				st=fw_card(icdev,0,&snCard);
				if(st){
					showMsg(_T("fw_card Error!"));
						return;
				}
				else{
					showMsg(_T("fw_card OK!"));
					strCard.Format(L"Card Serial Number: %u",snCard);
					showMsg(strCard);
				}
				//Reset 复位
				unsigned char rlen;
				unsigned char rData[256]={0};
				unsigned char showData[256]={0};
				st=fw_pro_reset(
					icdev,
					&rlen,
					rData);
				if(st){
					showMsg(_T("fw_pro_reset Error!"));
					strError.Format(L"Error code: %d",st);
					showMsg(strError);
					return;
				}
				
				showMsg(_T("fw_pro_reset OK!"));
				CString strResetInfo(L"Reset Information: ");
				
				hex_a(showData,rData,rlen*2);
				
				strResetInfo+=showData;
				showMsg(strResetInfo);

				//发送命令
				unsigned char srvBuffer[256];
				unsigned char sendlen=75;
				unsigned char revBuffer[256];
				unsigned char revstr[512]={0};
				unsigned char ftt=9;
				unsigned char fFG=7;//
				unsigned char revlen;
				
				CString strCommand(L"00A404000752736120417070");//选择文件
			//	m_edtCmd.GetWindowText(strCommand);
				
				int strlen=strCommand.GetLength();
				unsigned char cmdbuf[500];
				memcpy(cmdbuf,strCommand.GetBuffer(strlen),strlen);
				strCommand.ReleaseBuffer();
				
				a_hex((unsigned char*)srvBuffer,(unsigned char*)cmdbuf,strlen/2);
				sendlen=strlen/2;
				
				
				st=fw_pro_commandlink
					(
					icdev,//端口标识符
					sendlen,//发送的信息长度
					srvBuffer,//存放要发送的信息
					&revlen,//返回信息的长度
					revBuffer,//存放返回的信息
					ftt,//延迟时间，单位为：10ms
					fFG//分割长度。建议此值小于64
					);
				if(st)
				{
					showMsg(_T("fw_pro_commandlink Error!"));
					return;
				}
				
				showMsg(_T("fw_pro_commandlink OK!"));
				strResetInfo.Format(L"Information returned: ");
				
				hex_a(revstr,revBuffer,revlen*2);
				
				strResetInfo+=revstr;
				showMsg(strResetInfo);
			}
			break;
		case 6://desfire
			{
				unsigned char sessionKey[128];
				CString strError;
				CString strCard;

				//RF reset
				st=fw_reset( (HANDLE)icdev,10);
				if(st){
					showMsg(_T("fw_reset error!"));
					return;
				}
				showMsg(_T("fw_reset OK!"));

				//find card
				unsigned long isnr;
				//unsigned char size;
				CString strsnr1,strsnr2;
				st=fw_card(icdev,1,&isnr);
				if(st)
				{
					showMsg(_T("fw_card Error!"));
					return ;
				}
				strsnr1.Format(_T("%x"),isnr);

				//第二次防冲突
				st=fw_anticoll2(icdev,0,&isnr);
				if(st)
				{
					showMsg(_T("fw_anticoll2 Error!"));
					return ;
				}
				strsnr2.Format(_T("%x"),isnr);
				
				//第二次选卡
				st=fw_select2(icdev,isnr);
				if(st)
				{
					showMsg(_T("fw_select2 Error!"));
					return ;
				}
				
				showMsg(_T("Card Serial Number: ")+strsnr1+strsnr2);

				//card reset
				unsigned char rlen;
				unsigned char rebuf[100]={0};
				unsigned char showbuf[200]={0};
				
				st=fw_reset_desfire(icdev,&rlen,rebuf);
				if(st)
				{
					showMsg(_T("fw_reset_desfire Error!"));
					strError.Format(_T("Error Code: %d"),st);
					showMsg(strError);
					return;
				}
				
				hex_a(showbuf,rebuf,2*rlen);
				
				showMsg(_T("Card Reset Ok!Reset Information:")+CString(showbuf));

			

				//authenicate master key
				unsigned char Mkey[17]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
										0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

				st=fw_authen_desfire(icdev,0, (char*)Mkey,sessionKey);

				if(st){
					showMsg(_T("Authenication of Master Key Error!"));
					return;
				}
				else
					showMsg(_T("Authenication of Master Key Ok!"));


				//format card 
				//make sure current card is for test before format!
				st=fw_formatPICC_desfire(icdev);
				if(st)
				{
					showMsg(_T("Format card Error!"));
					strError.Format(_T("Error code: %d"),st);
					showMsg(strError);
					return;
				}
				showMsg(_T("Format card OK!"));


				//Add a application
				unsigned char aidbuf[4]={0x00,0x00,0x01};//3字节AID
				unsigned char keyset=0x0f;//1字节keysetting
				unsigned char numOfKey=0x0e;//1字节Num of key
				
				st=fw_createApp_desfire(icdev,aidbuf,keyset,numOfKey);
				if(st)
				{
					showMsg("New AID Create Error!");
					return;
				}
				
				showMsg("New AID Create OK!");

				//select this application
				int flag=fw_selectApp_desfire(icdev,aidbuf);
				if(flag)
				{
					showMsg("Select App Error!");
					return;
				}
				showMsg("Select App OK");

				
				//add a file ,a simple data file
				unsigned char fileid=0x01;
				unsigned char comset=0x01;
				unsigned char accessRight[3]={0xee,0xee};
				unsigned char fileSize[4]={0x20,0x00,0x00};
				st=fw_createDataFile_desfire(icdev,fileid,comset,accessRight,fileSize);
				if(flag)
				{
					showMsg("Create Data File Error!");
				}
				else
					showMsg("Create Data File OK!");




				//write data
				int m_iOffset=0;
				int m_iLength=9;
				unsigned char wdata[9]={'1','2','3','4',',','a','b','c','d'};

				st=fw_write_desfire(icdev,fileid,m_iOffset,m_iLength,wdata,(char*)sessionKey);
				if(st)
				{
					showMsg("Write Data Error");
					return;
				}
				showMsg("Write OK!");

				//read data
				unsigned char revdata[100];
				st=fw_read_desfire(icdev,fileid,m_iOffset,m_iLength,revdata,(char*)sessionKey);
				if(st)
				{
					showMsg("Read Data Error!");
					return;
				}

				showMsg("Read OK!");
				//show data
				unsigned char revDataHex[600]={0};
				hex_a(revDataHex,revdata,m_iLength*2);

				showMsg((CString)revdata);//show read data as ASCS
				showMsg((CString)revDataHex);//show read data as hex string

				//delete file
				st=fw_delFile_desfire(icdev,fileid);
				if(st)
				{
					showMsg("Delete This File Error!");
					return;
				}
				showMsg(_T("This file Deleted OK!"));
				

				//先验证主密钥
				st=fw_authen_desfire(icdev,0, (char*)Mkey,sessionKey);

				//delete application
				
				st=fw_delAID_desfire(icdev,aidbuf);
				if(st)
				{
					showMsg(_T("Delete this App Error!"));
					return ;
				}
				
				showMsg(_T("The App Deleted OK!"));

				break;


			}
	default:
		showMsg(L"Chose Card type to  test first!");
		break;
	}
}
void CTestDlg::ClearMsg()
{
	UpdateData(TRUE);

	m_strMsg="";

	UpdateData(FALSE);
}
void CTestDlg::showMsg(CString strmsg)
{
	UpdateData(TRUE);

	m_strMsg+=strmsg;
	m_strMsg+=L"\r\n";

	UpdateData(FALSE);
}